// 角色管理组件
<template>
  <div>
    <!-- 面包屑导航区 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/mangerHome' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片视图区 -->
    <el-card>
      <el-row>
        <el-col>
          <el-button type="primary" @click="addRoles">添加角色</el-button>
        </el-col>
      </el-row>
      <!-- 列表区 -->
      <el-table :data="rolesList" border stripe>
        <el-table-column type="expand">  <!-- 展开列 -->
          <template slot-scope="scope"> 
            <el-row v-for="(item1,i1) in scope.row.children" :key="item1.id" :class="['boderbottom', i1 === 0 ? 'bordertop' : '','colcenter']">
              <!-- 渲染一级权限 -->
              <el-col :span="5"> 
                <el-tag closable @close="removeRightTagById(scope.row,item1.id)">{{item1.authName}}</el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!-- 渲染二级权限 -->
              <el-col :span="19">
                <el-row v-for="(item2,i2) in item1.children" :key="item2.id" :class="[i2 === 0 ? '' : 'bordertop','colcenter']">
                  <el-col :span="6">
                    <el-tag type="success" closable @close="removeRightTagById(scope.row,item2.id)">{{item2.authName}}</el-tag>
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <!-- 渲染三级权限 -->
                  <el-col :span="18">
                    <el-tag type="warning" v-for="(item3) in item2.children" :key="item3.id" closable @close="removeRightTagById(scope.row,item3.id)">{{item3.authName}}</el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column> 
        <el-table-column type="index"></el-table-column> <!-- 索引列 -->
        <el-table-column label="角色名称" prop="roleName"></el-table-column>
        <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
        <el-table-column label="操作" width="300px">
          <template slot-scope="scope">
            <el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditRolesDialog(scope.row)">编辑</el-button>
            <el-button size="mini" type="danger" icon="el-icon-delete" @click="DeleteRolesById(scope.row)">删除</el-button>
            <el-button size="mini" type="warning" icon="el-icon-setting" @click="showRightDialog(scope.row)">分配权限</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 分配权限对话框 -->
    <el-dialog title="分配权限" :visible.sync="rightDialogVisible" width="50%" @close="rightDialogVisibleClose">
      <!-- 树形结构 -->
      <el-tree :data="rightList" :props="treeprops" show-checkbox node-key="id" default-expand-all :default-checked-keys="defkey" ref="treeRefs">
      </el-tree>
      <span slot="footer" class="dialog-footer">
        <el-button @click="rightDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addRolesRight">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 添加角色对话框 -->
    <el-dialog title="添加角色" :visible.sync="addRolesDialogVisible" width="50%" @close="addRolesDialogVisibleClose">
      <!-- 表单区 -->
      <el-form :model="addRolesFrom" label-width="100px" class="demo-ruleForm"  :rules="addRolesFromRules" ref="addRolesFromRef">
        <el-form-item label="角色名称"  prop="roleName">
          <el-input v-model="addRolesFrom.roleName"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input type="text" v-model="addRolesFrom.roleDesc"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addRolesDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveAddRoles">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 编辑角色信息对话框 -->
    <el-dialog title="编辑角色" :visible.sync="editRolesDialogVisible" width="50%" @close="editRolesDialogVisibleClose">
      <!-- 表单区 -->
      <el-form :model="editForm" label-width="100px" class="demo-ruleForm"  :rules="addRolesFromRules" ref="editFromRef">
        <el-form-item label="角色ID">
          <el-input v-model="editForm.roleId" disabled></el-input>
        </el-form-item>
        <el-form-item label="角色名称"  prop="roleName">
          <el-input v-model="editForm.roleName"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input type="text" v-model="editForm.roleDesc"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="editRolesDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveEditForm">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      rolesList:[],    //保存后台获取到的角色列表
      rightDialogVisible:false,    //分配权限对话框de显示隐藏
      rightList:[],     //保存后台获取到的权限列表
      treeprops: {    //树形控件绑定的属性
        label: 'authName',
        children: 'children'
      },
      defkey:[],     //树形结构绑定的默认勾选权限的数组
      rolesId:'',    //当前操作的角色id
      addRolesDialogVisible:false,   //添加角色对话框显示隐藏
      addRolesFrom:{    //添加角色时表单绑定的数据
        roleName:'',
        roleDesc:''
      },
      addRolesFromRules:{   //添加角色时表单绑定的验证规则
        roleName:[   //角色名称验证规则
          { required: true, message: '请输入角色名称', trigger: 'blur' },
          { min: 2, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur' }
        ],
        roleDesc:[   //角色描述验证规则
          { required: true, message: '请输入角色描述', trigger: 'blur' },
          { min: 5, max: 20, message: '长度在 5 到 20 个字符', trigger: 'blur' }
        ]
      },
      editRolesDialogVisible:false,    //编辑角色的对话框
      editForm:{},   //保存编辑的数据
    }
  },
  created() {   //挂载前
    this.getRolesList()   //调用获取后台数据函数
  },
  methods: {
    async getRolesList(){   //获取后台角色列表数据
      const {data:res} = await this.$http.get('roles')   //发起请求
      if(res.meta.status !== 200){   //请求失败
        return this.$message.error('获取角色列表失败！')
      }
      // 请求成功
      this.rolesList = res.data   //保存数据
      // console.log(this.rolesList)
    },
    async removeRightTagById(roles,rightId){   //监听权限tag响应操作 通过id进行删除操作
      // elm组件自带弹窗   (弹窗有问题)
      const confirmResult = await this.$confirm.confirm('此操作将永久删除该权限, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
          // center: true
        }).catch(err => err)

      // console.log(confirmResult)
      // confirmResult的值为confirm 则是确认删除
      // confirmResult的值为cancle 则是取消删除
      if(confirmResult !== 'confirm'){   //点击取消或者关闭
        return this.$message.info('已取消删除')
      }

      // // 点击确认 发起请求 删除数据 关闭弹窗 更新列表
      const {data:res} = await this.$http.delete(`roles/${roles.id}/rights/${rightId}`)   //发起请求
      // console.log(res)
      if(res.meta.status !== 200){    //请求失败
        return this.$message.error('访问后台数据失败，无法进行权限删除！')
      }
      // // 请求成功
      this.$message.success('删除权限成功！')   //消息提示弹窗
      roles.children = res.data    //更新数据列表
    },
    async showRightDialog(roles){    //分配权限按钮响应
      this.rolesId = roles.id    //保存当前操作的角色id
      const {data:res} = await this.$http.get('rights/tree')    //发起请求
      if(res.meta.status !== 200 ){    //请求失败
        return this.$message.error('访问后台数据失败，无法获取到权限列表！')
      }
      // 请求成功
      this.rightList = res.data   //保存获取到的权限列表
      // console.log(res)
      // this.$message.success('成功获取权限列表！')
     
      this.getLeafKeys(roles,this.defkey)   // 获取三级权限数据
      this.rightDialogVisible = true   
    },
    rightDialogVisibleClose(){   //监听分配权限对话框关闭
      this.defkey = []   //清空数组
    },
    // node当前结点  arr要保存的数组
    getLeafKeys(node,arr){   //通过递归调用获取三级权限数据 保存到defkey数组中
      if(!node.children){    //如果当前节点没有children属性则说明是三级权限
        return arr.push(node.id)   //将这个结点的id保存到数组中
      }
      // 如果不是三级结点 则循环遍历
      node.children.forEach((item)=>{
        this.getLeafKeys(item,arr)
      })
    },
    async addRolesRight(){   //监听分配权限对话框的确定按钮事件
      const keys = [   //保存我们所分配的权限id
        ...this.$refs.treeRefs.getCheckedKeys(),   //getCheckedKeys获取当前结点全部选中的结点数组
        ...this.$refs.treeRefs.getHalfCheckedKeys()   //getHalfCheckedKeys获取当前节点半选中的全部结点数组
      ]

      const keyStr = keys.join(',')   //用逗号拆分数组并变成一个字符串
      // 发起请求
      const {data:res} = await this.$http.post(`roles/${this.rolesId}/rights`,{rids:keyStr})
      if(res.meta.status !== 200){    //请求失败
        this.$message.error('后台数据请求失败！')
      }
      // 请求成功
      this.$message.success('添加权限成功！')
      this.getRolesList()    //更新列表
      this.rightDialogVisible = false   //关闭对话框
    },
    addRoles(){   //添加角色按钮响应
      this.addRolesDialogVisible = true
    },
    saveAddRoles(){   //添加角色确认按钮响应事件
      this.$refs.addRolesFromRef.validate(async vali=>{   //表单预验证
        if(!vali) return   //预验证不通过 不进行操作
        const {data:res} = await this.$http.post('roles',this.addRolesFrom)    //发起请求
        // console.log(res)
        if(res.meta.status !== 201){   //请求失败
          return this.$message.error('请求后台数据失败，无法进行角色添加！')
        }
        // 请求成功
        this.$message.success('添加角色成功！')
        this.getRolesList()   //更新列表
        this.addRolesDialogVisible = false   //关闭对话框
      })
    },
    addRolesDialogVisibleClose(){   //添加角色对话框关闭
      this.$refs.addRolesFromRef.resetFields()   //表单重置
    },
    async DeleteRolesById(roles){   //根据角色id删除角色
      const confirmResult = await this.$confirm.confirm('此操作将永久删除“'+roles.roleName+'”角色, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        // center: true
      }).catch(err => err)
      if(confirmResult !== 'confirm'){
        return this.$message.info('已取消删除操作')
      }

      const {data:res} = await this.$http.delete('roles/' + roles.id)   //发起请求
      if(res.meta.status !== 200 ){
        return this.$message.error('访问后台数据失败，无法进行删除！')
      }
      // 请求成功
      this.$message.success('删除角色成功！')
      this.getRolesList()   //更新列表
    }, 
    async showEditRolesDialog(roles){   //编辑角色对话框
      // 得到当前数据的id 向后台发起请求 获取当前数据赋值给editForm
      const {data:res} = await this.$http.get('roles/' + roles.id)   //发起请求
      if(res.meta.status !== 200 ){
        return this.$message.error('访问后台数据失败，无法进行编辑！')
      }
      // 请求成功
      this.editForm = res.data
      this.editRolesDialogVisible = true
    },
    editRolesDialogVisibleClose(){   //关闭编辑角色对话框
      this.$refs.editFromRef.resetFields()    //表单重置
    },
    saveEditForm(){    //向后台提交编辑后的数据
      this.$refs.editFromRef.validate(async vali=>{
        if(!vali) return   //表单预验证失败 没有任何操作
        // 表单预验证成功，向后台发起请求 保存新的数据 更新列表 关闭对话框
        const {data:res} = await this.$http.put('roles/'+this.editForm.roleId,{roleName:this.editForm.roleName,roleDesc:this.editForm.roleDesc})  //发起请求
        // console.log(res)
        if(res.meta.status !== 200){   //请求失败
          return this.$message.error('访问后台数据失败，无法提交修改！')
        }
        // 请求成功
        this.editRolesDialogVisible = false
        this.$message.success('编辑角色成功！')
        this.getRolesList()
      })
    }
  }
}
</script>

<style>
.el-tag{
  margin: 7px;
}
.bordertop{
  border-top: 1px solid #ddd;
}
.boderbottom{
  border-bottom: 1px solid #ddd;
}
/* 让一级和二级渲染垂直居中 */
.colcenter{  
  display: flex;   
  align-items: center;
}
</style>